import { Models } from '../common/typings/model'
import { DataBaseFailed } from '../core/HttpException'
import { humpToLineObject, lineToHumpObject } from '../common/utils/utils'
const mongoClient = require('mongodb').MongoClient
const ObjectId = require('mongodb').ObjectId

const url =
  process.env.NODE_ENV === 'development'
    ? // 'mongodb://localhost:27017/'
      'mongodb://admin:123456@1.116.40.155:27017/'
    : 'mongodb://admin:123456@1.116.40.155:27017/'
interface DBCommandOption {
  dbName: string
  collectionName: string
  isPagination: boolean
  pageSize: number
  pageNum: number
}

interface DBCommand {
  [propsName: string]: any
}
// const client = new mongoClient(url, {useNewUrlParser: true})
// console.log(client)
export default class DB {
  private static connect(callback: Function) {
    mongoClient.connect(url, (err: { message: string }, client: any) => {
      if (err) {
        throw new DataBaseFailed('数据库连接出错' + ':' + err.message)
      }
      callback(client)
    })
  }
  /*
   * 数据库查询
   * @param command 过滤条件
   * @param option 表明和集合名
   */
  public static async query(command: DBCommand = {}, option: DBCommandOption): Promise<Models.Result> {
    try {
      return new Promise<Models.Result>(async (resolve, reject) => {
        this.connect(async (client: any) => {
          const col = client.db(option.dbName).collection(option.collectionName)
          let total = 0
          const page = (data: any) => {
            if (option.isPagination) {
              // eslint-disable-next-line @typescript-eslint/no-unsafe-return
              return data.skip((option.pageNum - 1) * option.pageSize).limit(option.pageSize)
            } else {
              // eslint-disable-next-line @typescript-eslint/no-unsafe-return
              return data
            }
          }
          const query = col.find(humpToLineObject(command))
          // const query = col.find({parent_id: null})

          total = await query.count()
          page(query)
            .toArray()
            .then((items: any[]) => {
              client?.close()
              const result: Models.Result = {
                msg: 'ok',
                state: 1,
                // results: items,
                results: {
                  list: items.map(lineToHumpObject),
                  total: option.isPagination ? total : undefined,
                },
              }
              resolve(result)
            })
        })
      })
    } catch (err) {
      // console.log(command)
      throw new DataBaseFailed()
    }
  }

  public static ObjectId = ObjectId
}
